bindings.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. """
  2. This module uses ctypes to bind a whole bunch of functions and constants from
  3. SecureTransport. The goal here is to provide the low-level API to
  4. SecureTransport. These are essentially the C-level functions and constants, and
  5. they're pretty gross to work with.
  6. This code is a bastardised version of the code found in Will Bond's oscrypto
  7. library. An enormous debt is owed to him for blazing this trail for us. For
  8. that reason, this code should be considered to be covered both by urllib3's
  9. license and by oscrypto's:
  10. Copyright (c) 2015-2016 Will Bond <will@wbond.net>
  11. Permission is hereby granted, free of charge, to any person obtaining a
  12. copy of this software and associated documentation files (the "Software"),
  13. to deal in the Software without restriction, including without limitation
  14. the rights to use, copy, modify, merge, publish, distribute, sublicense,
  15. and/or sell copies of the Software, and to permit persons to whom the
  16. Software is furnished to do so, subject to the following conditions:
  17. The above copyright notice and this permission notice shall be included in
  18. all copies or substantial portions of the Software.
  19. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25. DEALINGS IN THE SOFTWARE.
  26. """
  27. from __future__ import absolute_import
  28. import platform
  29. from ctypes.util import find_library
  30. from ctypes import (
  31. c_void_p,
  32. c_int32,
  33. c_char_p,
  34. c_size_t,
  35. c_byte,
  36. c_uint32,
  37. c_ulong,
  38. c_long,
  39. c_bool,
  40. )
  41. from ctypes import CDLL, POINTER, CFUNCTYPE
  42. security_path = find_library("Security")
  43. if not security_path:
  44. raise ImportError("The library Security could not be found")
  45. core_foundation_path = find_library("CoreFoundation")
  46. if not core_foundation_path:
  47. raise ImportError("The library CoreFoundation could not be found")
  48. version = platform.mac_ver()[0]
  49. version_info = tuple(map(int, version.split(".")))
  50. if version_info < (10, 8):
  51. raise OSError(
  52. "Only OS X 10.8 and newer are supported, not %s.%s"
  53. % (version_info[0], version_info[1])
  54. )
  55. Security = CDLL(security_path, use_errno=True)
  56. CoreFoundation = CDLL(core_foundation_path, use_errno=True)
  57. Boolean = c_bool
  58. CFIndex = c_long
  59. CFStringEncoding = c_uint32
  60. CFData = c_void_p
  61. CFString = c_void_p
  62. CFArray = c_void_p
  63. CFMutableArray = c_void_p
  64. CFDictionary = c_void_p
  65. CFError = c_void_p
  66. CFType = c_void_p
  67. CFTypeID = c_ulong
  68. CFTypeRef = POINTER(CFType)
  69. CFAllocatorRef = c_void_p
  70. OSStatus = c_int32
  71. CFDataRef = POINTER(CFData)
  72. CFStringRef = POINTER(CFString)
  73. CFArrayRef = POINTER(CFArray)
  74. CFMutableArrayRef = POINTER(CFMutableArray)
  75. CFDictionaryRef = POINTER(CFDictionary)
  76. CFArrayCallBacks = c_void_p
  77. CFDictionaryKeyCallBacks = c_void_p
  78. CFDictionaryValueCallBacks = c_void_p
  79. SecCertificateRef = POINTER(c_void_p)
  80. SecExternalFormat = c_uint32
  81. SecExternalItemType = c_uint32
  82. SecIdentityRef = POINTER(c_void_p)
  83. SecItemImportExportFlags = c_uint32
  84. SecItemImportExportKeyParameters = c_void_p
  85. SecKeychainRef = POINTER(c_void_p)
  86. SSLProtocol = c_uint32
  87. SSLCipherSuite = c_uint32
  88. SSLContextRef = POINTER(c_void_p)
  89. SecTrustRef = POINTER(c_void_p)
  90. SSLConnectionRef = c_uint32
  91. SecTrustResultType = c_uint32
  92. SecTrustOptionFlags = c_uint32
  93. SSLProtocolSide = c_uint32
  94. SSLConnectionType = c_uint32
  95. SSLSessionOption = c_uint32
  96. try:
  97. Security.SecItemImport.argtypes = [
  98. CFDataRef,
  99. CFStringRef,
  100. POINTER(SecExternalFormat),
  101. POINTER(SecExternalItemType),
  102. SecItemImportExportFlags,
  103. POINTER(SecItemImportExportKeyParameters),
  104. SecKeychainRef,
  105. POINTER(CFArrayRef),
  106. ]
  107. Security.SecItemImport.restype = OSStatus
  108. Security.SecCertificateGetTypeID.argtypes = []
  109. Security.SecCertificateGetTypeID.restype = CFTypeID
  110. Security.SecIdentityGetTypeID.argtypes = []
  111. Security.SecIdentityGetTypeID.restype = CFTypeID
  112. Security.SecKeyGetTypeID.argtypes = []
  113. Security.SecKeyGetTypeID.restype = CFTypeID
  114. Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef]
  115. Security.SecCertificateCreateWithData.restype = SecCertificateRef
  116. Security.SecCertificateCopyData.argtypes = [SecCertificateRef]
  117. Security.SecCertificateCopyData.restype = CFDataRef
  118. Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
  119. Security.SecCopyErrorMessageString.restype = CFStringRef
  120. Security.SecIdentityCreateWithCertificate.argtypes = [
  121. CFTypeRef,
  122. SecCertificateRef,
  123. POINTER(SecIdentityRef),
  124. ]
  125. Security.SecIdentityCreateWithCertificate.restype = OSStatus
  126. Security.SecKeychainCreate.argtypes = [
  127. c_char_p,
  128. c_uint32,
  129. c_void_p,
  130. Boolean,
  131. c_void_p,
  132. POINTER(SecKeychainRef),
  133. ]
  134. Security.SecKeychainCreate.restype = OSStatus
  135. Security.SecKeychainDelete.argtypes = [SecKeychainRef]
  136. Security.SecKeychainDelete.restype = OSStatus
  137. Security.SecPKCS12Import.argtypes = [
  138. CFDataRef,
  139. CFDictionaryRef,
  140. POINTER(CFArrayRef),
  141. ]
  142. Security.SecPKCS12Import.restype = OSStatus
  143. SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t))
  144. SSLWriteFunc = CFUNCTYPE(
  145. OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)
  146. )
  147. Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc]
  148. Security.SSLSetIOFuncs.restype = OSStatus
  149. Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t]
  150. Security.SSLSetPeerID.restype = OSStatus
  151. Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef]
  152. Security.SSLSetCertificate.restype = OSStatus
  153. Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean]
  154. Security.SSLSetCertificateAuthorities.restype = OSStatus
  155. Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef]
  156. Security.SSLSetConnection.restype = OSStatus
  157. Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t]
  158. Security.SSLSetPeerDomainName.restype = OSStatus
  159. Security.SSLHandshake.argtypes = [SSLContextRef]
  160. Security.SSLHandshake.restype = OSStatus
  161. Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
  162. Security.SSLRead.restype = OSStatus
  163. Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
  164. Security.SSLWrite.restype = OSStatus
  165. Security.SSLClose.argtypes = [SSLContextRef]
  166. Security.SSLClose.restype = OSStatus
  167. Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)]
  168. Security.SSLGetNumberSupportedCiphers.restype = OSStatus
  169. Security.SSLGetSupportedCiphers.argtypes = [
  170. SSLContextRef,
  171. POINTER(SSLCipherSuite),
  172. POINTER(c_size_t),
  173. ]
  174. Security.SSLGetSupportedCiphers.restype = OSStatus
  175. Security.SSLSetEnabledCiphers.argtypes = [
  176. SSLContextRef,
  177. POINTER(SSLCipherSuite),
  178. c_size_t,
  179. ]
  180. Security.SSLSetEnabledCiphers.restype = OSStatus
  181. Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)]
  182. Security.SSLGetNumberEnabledCiphers.restype = OSStatus
  183. Security.SSLGetEnabledCiphers.argtypes = [
  184. SSLContextRef,
  185. POINTER(SSLCipherSuite),
  186. POINTER(c_size_t),
  187. ]
  188. Security.SSLGetEnabledCiphers.restype = OSStatus
  189. Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)]
  190. Security.SSLGetNegotiatedCipher.restype = OSStatus
  191. Security.SSLGetNegotiatedProtocolVersion.argtypes = [
  192. SSLContextRef,
  193. POINTER(SSLProtocol),
  194. ]
  195. Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus
  196. Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)]
  197. Security.SSLCopyPeerTrust.restype = OSStatus
  198. Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef]
  199. Security.SecTrustSetAnchorCertificates.restype = OSStatus
  200. Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean]
  201. Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
  202. Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)]
  203. Security.SecTrustEvaluate.restype = OSStatus
  204. Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef]
  205. Security.SecTrustGetCertificateCount.restype = CFIndex
  206. Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex]
  207. Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef
  208. Security.SSLCreateContext.argtypes = [
  209. CFAllocatorRef,
  210. SSLProtocolSide,
  211. SSLConnectionType,
  212. ]
  213. Security.SSLCreateContext.restype = SSLContextRef
  214. Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean]
  215. Security.SSLSetSessionOption.restype = OSStatus
  216. Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol]
  217. Security.SSLSetProtocolVersionMin.restype = OSStatus
  218. Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol]
  219. Security.SSLSetProtocolVersionMax.restype = OSStatus
  220. Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
  221. Security.SecCopyErrorMessageString.restype = CFStringRef
  222. Security.SSLReadFunc = SSLReadFunc
  223. Security.SSLWriteFunc = SSLWriteFunc
  224. Security.SSLContextRef = SSLContextRef
  225. Security.SSLProtocol = SSLProtocol
  226. Security.SSLCipherSuite = SSLCipherSuite
  227. Security.SecIdentityRef = SecIdentityRef
  228. Security.SecKeychainRef = SecKeychainRef
  229. Security.SecTrustRef = SecTrustRef
  230. Security.SecTrustResultType = SecTrustResultType
  231. Security.SecExternalFormat = SecExternalFormat
  232. Security.OSStatus = OSStatus
  233. Security.kSecImportExportPassphrase = CFStringRef.in_dll(
  234. Security, "kSecImportExportPassphrase"
  235. )
  236. Security.kSecImportItemIdentity = CFStringRef.in_dll(
  237. Security, "kSecImportItemIdentity"
  238. )
  239. # CoreFoundation time!
  240. CoreFoundation.CFRetain.argtypes = [CFTypeRef]
  241. CoreFoundation.CFRetain.restype = CFTypeRef
  242. CoreFoundation.CFRelease.argtypes = [CFTypeRef]
  243. CoreFoundation.CFRelease.restype = None
  244. CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef]
  245. CoreFoundation.CFGetTypeID.restype = CFTypeID
  246. CoreFoundation.CFStringCreateWithCString.argtypes = [
  247. CFAllocatorRef,
  248. c_char_p,
  249. CFStringEncoding,
  250. ]
  251. CoreFoundation.CFStringCreateWithCString.restype = CFStringRef
  252. CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding]
  253. CoreFoundation.CFStringGetCStringPtr.restype = c_char_p
  254. CoreFoundation.CFStringGetCString.argtypes = [
  255. CFStringRef,
  256. c_char_p,
  257. CFIndex,
  258. CFStringEncoding,
  259. ]
  260. CoreFoundation.CFStringGetCString.restype = c_bool
  261. CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex]
  262. CoreFoundation.CFDataCreate.restype = CFDataRef
  263. CoreFoundation.CFDataGetLength.argtypes = [CFDataRef]
  264. CoreFoundation.CFDataGetLength.restype = CFIndex
  265. CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef]
  266. CoreFoundation.CFDataGetBytePtr.restype = c_void_p
  267. CoreFoundation.CFDictionaryCreate.argtypes = [
  268. CFAllocatorRef,
  269. POINTER(CFTypeRef),
  270. POINTER(CFTypeRef),
  271. CFIndex,
  272. CFDictionaryKeyCallBacks,
  273. CFDictionaryValueCallBacks,
  274. ]
  275. CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef
  276. CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef]
  277. CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef
  278. CoreFoundation.CFArrayCreate.argtypes = [
  279. CFAllocatorRef,
  280. POINTER(CFTypeRef),
  281. CFIndex,
  282. CFArrayCallBacks,
  283. ]
  284. CoreFoundation.CFArrayCreate.restype = CFArrayRef
  285. CoreFoundation.CFArrayCreateMutable.argtypes = [
  286. CFAllocatorRef,
  287. CFIndex,
  288. CFArrayCallBacks,
  289. ]
  290. CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef
  291. CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p]
  292. CoreFoundation.CFArrayAppendValue.restype = None
  293. CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef]
  294. CoreFoundation.CFArrayGetCount.restype = CFIndex
  295. CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
  296. CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p
  297. CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll(
  298. CoreFoundation, "kCFAllocatorDefault"
  299. )
  300. CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(
  301. CoreFoundation, "kCFTypeArrayCallBacks"
  302. )
  303. CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(
  304. CoreFoundation, "kCFTypeDictionaryKeyCallBacks"
  305. )
  306. CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(
  307. CoreFoundation, "kCFTypeDictionaryValueCallBacks"
  308. )
  309. CoreFoundation.CFTypeRef = CFTypeRef
  310. CoreFoundation.CFArrayRef = CFArrayRef
  311. CoreFoundation.CFStringRef = CFStringRef
  312. CoreFoundation.CFDictionaryRef = CFDictionaryRef
  313. except (AttributeError):
  314. raise ImportError("Error initializing ctypes")
  315. class CFConst(object):
  316. """
  317. A class object that acts as essentially a namespace for CoreFoundation
  318. constants.
  319. """
  320. kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)
  321. class SecurityConst(object):
  322. """
  323. A class object that acts as essentially a namespace for Security constants.
  324. """
  325. kSSLSessionOptionBreakOnServerAuth = 0
  326. kSSLProtocol2 = 1
  327. kSSLProtocol3 = 2
  328. kTLSProtocol1 = 4
  329. kTLSProtocol11 = 7
  330. kTLSProtocol12 = 8
  331. # SecureTransport does not support TLS 1.3 even if there's a constant for it
  332. kTLSProtocol13 = 10
  333. kTLSProtocolMaxSupported = 999
  334. kSSLClientSide = 1
  335. kSSLStreamType = 0
  336. kSecFormatPEMSequence = 10
  337. kSecTrustResultInvalid = 0
  338. kSecTrustResultProceed = 1
  339. # This gap is present on purpose: this was kSecTrustResultConfirm, which
  340. # is deprecated.
  341. kSecTrustResultDeny = 3
  342. kSecTrustResultUnspecified = 4
  343. kSecTrustResultRecoverableTrustFailure = 5
  344. kSecTrustResultFatalTrustFailure = 6
  345. kSecTrustResultOtherError = 7
  346. errSSLProtocol = -9800
  347. errSSLWouldBlock = -9803
  348. errSSLClosedGraceful = -9805
  349. errSSLClosedNoNotify = -9816
  350. errSSLClosedAbort = -9806
  351. errSSLXCertChainInvalid = -9807
  352. errSSLCrypto = -9809
  353. errSSLInternal = -9810
  354. errSSLCertExpired = -9814
  355. errSSLCertNotYetValid = -9815
  356. errSSLUnknownRootCert = -9812
  357. errSSLNoRootCert = -9813
  358. errSSLHostNameMismatch = -9843
  359. errSSLPeerHandshakeFail = -9824
  360. errSSLPeerUserCancelled = -9839
  361. errSSLWeakPeerEphemeralDHKey = -9850
  362. errSSLServerAuthCompleted = -9841
  363. errSSLRecordOverflow = -9847
  364. errSecVerifyFailed = -67808
  365. errSecNoTrustSettings = -25263
  366. errSecItemNotFound = -25300
  367. errSecInvalidTrustSettings = -25262
  368. # Cipher suites. We only pick the ones our default cipher string allows.
  369. # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values
  370. TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C
  371. TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030
  372. TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B
  373. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F
  374. TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9
  375. TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8
  376. TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F
  377. TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
  378. TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024
  379. TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028
  380. TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A
  381. TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014
  382. TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
  383. TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
  384. TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023
  385. TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027
  386. TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009
  387. TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013
  388. TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
  389. TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
  390. TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D
  391. TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
  392. TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
  393. TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
  394. TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
  395. TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
  396. TLS_AES_128_GCM_SHA256 = 0x1301
  397. TLS_AES_256_GCM_SHA384 = 0x1302
  398. TLS_AES_128_CCM_8_SHA256 = 0x1305
  399. TLS_AES_128_CCM_SHA256 = 0x1304